package com.sdu.game.websocket;

import com.sdu.game.controller.Shujuk;
import com.sdu.game.mapper.ArticleMapper;
import com.sdu.game.mapper.PlayerMapper;
import com.sdu.game.mapper.RoomMapper;
import com.sdu.game.pojo.Player;
import com.sdu.game.pojo.PlayerExample;
import com.sdu.game.pojo.Room;
import com.sdu.game.pojo.RoomExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

//用户点击进入房间:使用webSocket,传入用户id，返回分配的房间信息
@ServerEndpoint("/webSocket/{sid}")
@Component
public class GameRoom {





    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。

    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    ConcurrentHashMap<String,Session> sessionList=new ConcurrentHashMap<>();

    private static ArrayList<String> userlistd=new ArrayList<>();


    public static ConcurrentHashMap<String, Session> getSessionPools() {
        return sessionPools;
    }

    public static void setSessionPools(ConcurrentHashMap<String, Session> sessionPools) {
        GameRoom.sessionPools = sessionPools;
    }

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if(session != null){
            synchronized (session) {
                System.out.println("发送数据：wwwwwwwwwwwwwfcrvvvvvvvvvvvvvvvvveeeeeee" );
                session.getBasicRemote().sendText(message);
            }
        }
    }
    //给指定用户发送信息
    public void sendInfo(String userName, String message){
        Session session = sessionPools.get(userName);
        try {
            sendMessage(session, message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void sendInfouser(String userName, String user){
        Session session = sessionPools.get(userName);
        try {
            if(session != null){
                synchronized (session) {
//                System.out.println("发送数据：" + message);
                    session.getBasicRemote().sendText(user);
                    System.out.println("类发送成功");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String userName){
        //使用用户id来作为session的唯一判断标准和数据库中的房间中的用户对应
        System.out.println(userName);
        Session sessiont= sessionPools.get(userName);

        //判断用户是否已经存在，同一人不能同时加入两个房间
        try {
            if(sessiont == null){
                synchronized (session) {
//                System.out.println("发送数据：" + message);
                    System.out.println("ssssssssssssssssssssssss");
                    sessionPools.put(userName, session);
                    addOnlineCount();//在线人数
//                    session.getBasicRemote().sendText(user);
//                    System.out.println("类发送成功");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

//只考虑一个房间的情况下，不需要对用户进行房间判断，获取到用户的准备请求后直接将信息返回给用户


//        准备


        //将用户添加到session中

        //查询paly看用户是否在房间中,没在则分配房间




        //用户分配房间


        //将房间结果广播出去



        //给用户分配房间，此处需要修改的数据库有：房间表添加用户；玩家表新建角色同时玩家表需要扩展属性（游戏状态，房间座位号）




        //此处得到房间信息,获取房间内用户的ID,昵称，座位号


        //将此时房间的信息回传给房间内每个座位用户的信息(座位号，昵称)打包回传给用户


        // 后端传参
        //收到前端数据（命令号+id）；
        //进入房间(1+id)
        //准备(2+id)









        //1.进入房间，传参 命令号+用户名（昵称）+座位号 '1,123,4'；
        //2.准备阶段广播的数据(命令号+座位号)；
        //3.游戏开始命令(命令号)；




        //可使用hasmap构建数据
        String Data_user="用户数据收取成功";//假想用户数据






//        ArrayList<String> idlist=new ArrayList<>();//存储和该用户同房间的用户id
//        //对每个用户发送消息
//
//        idlist.add(userName);
//
//        for(int i=0;i<idlist.size();i++){
//            Session sessiond= sessionPools.get(userName);
//            try {
//                sendMessage(sessiond, Data_user);
//            } catch(Exception e){
//                e.printStackTrace();
//                continue;
//            }
//
//        }


        System.out.println(sessionPools.toString());

//        System.out.println(userName + "加入webSocket！当前人数为" + onlineNum);
//        System.out.println(session.getId());
        try {
            sendMessage(session, "欢迎" + userName + "加入连接！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //关闭连接时调用
    //当玩家退出时需要将玩家连接关闭的同时，将其从数据库中删除
    @OnClose
    public void onClose(@PathParam(value = "sid") String userName){
        sessionPools.remove(userName);
        subOnlineCount();

        //数据库操作，userId，在玩家表中找到该玩家得到房间号，然后将玩家删除，同时在房间表中将用户删除

        System.out.println(userName + "断开webSocket连接！当前人数为" + onlineNum);
    }


    //收到客户端信息
    @OnMessage
    public void onMessage(String message) throws IOException {

        //接收前端用户的准备信息，获取请求者的Id，和座位号
        //针对只有一个房间的返回情况，游戏返回（命令号+座位号）
        String message1 = "2," + message.substring(2);

        userlistd.add(message);


        System.out.println(message);
        for (Session session : sessionPools.values()) {
            try {
                sendMessage(session, message1);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }

        System.out.println(userlistd.size());
        if (userlistd.size() == 6) {

            String message2 = "3";

            for (Session session : sessionPools.values()) {
                try {
                    sendMessage(session, message2);
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
            }


        }
    }


    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount(){
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

}